<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>JNet 框架 API 文档</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f8f9fa;
        }
        header {
            text-align: center;
            margin-bottom: 30px;
            padding-bottom: 10px;
            border-bottom: 1px solid #dee2e6;
            background-color: #fff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h1 {
            color: #2c3e50;
            margin-bottom: 10px;
        }
        .subtitle {
            color: #7f8c8d;
            font-size: 1.1em;
        }
        section {
            background-color: #fff;
            margin-bottom: 25px;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h2 {
            color: #3498db;
            border-bottom: 1px solid #eee;
            padding-bottom: 10px;
            margin-top: 0;
        }
        h3 {
            color: #2c3e50;
            margin-top: 20px;
        }
        pre {
            background-color: #2c3e50;
            color: #ecf0f1;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            font-size: 0.9em;
        }
        code {
            font-family: 'Courier New', monospace;
        }
        ul {
            padding-left: 20px;
        }
        li {
            margin-bottom: 8px;
        }
        .example-label {
            font-weight: bold;
            color: #e74c3c;
        }
    </style>
</head>
<body>

    <header>
        <h1>JNet 框架 API 文档</h1>
        <p class="subtitle">一个面向 AI 的核心概念与使用指南</p>
    </header>

    <section>
        <h2>概述</h2>
        <p>JNet 是一个基于 Java 异步 I/O (AIO) 能力构建的高性能、异步网络通信框架。它专为构建可扩展的 TCP 客户端和服务器而设计，强调模块化和数据处理管道，使其易于实现复杂的协议和业务逻辑。</p>
        <p>其核心思想是提供一种结构化的方式来处理网络 I/O，数据通过一系列可定制的处理单元流动，从而简化了复杂网络应用的开发。</p>
    </section>

    <section>
        <h2>核心概念</h2>

        <h3>AioServer (异步服务器)</h3>
        <p>用于创建异步 TCP 服务器的入口点。</p>
        <ul>
            <li><strong>创建:</strong> 使用静态工厂方法 <code>AioServer.newAioServer(ChannelConfig, PipelineInitializer)</code>。</li>
            <li><strong>生命周期:</strong>
                <ul>
                    <li><code>start()</code>: 将服务器绑定到端口并开始接受连接。</li>
                    <li><code>shutdown()</code> / <code>termination()</code>: 停止服务器并释放资源。</li>
                </ul>
            </li>
        </ul>

        <h3>ClientChannel (客户端通道)</h3>
        <p>用于创建异步 TCP 客户端连接的入口点。</p>
        <ul>
            <li><strong>创建:</strong> 使用静态工厂方法 <code>ClientChannel.newClient(ChannelConfig, PipelineInitializer)</code>。</li>
            <li><strong>生命周期:</strong>
                <ul>
                    <li><code>connect()</code>: 启动到服务器的连接。成功时返回 <code>true</code>。</li>
                    <li><code>alive()</code>: 检查连接当前是否被认为是活动的。</li>
                </ul>
            </li>
        </ul>

        <h3>Pipeline (管道)</h3>
        <p>JNet 的核心。一个 <code>Pipeline</code> 代表一个单一的网络连接（客户端或服务器端），并管理通过它的数据流。它作为一个管道，数据在被读取或写入网络时可以被处理或转换。</p>
        <ul>
            <li><strong>数据流:</strong>
                <ul>
                    <li><strong>入站 (Read):</strong> 从网络接收到的数据会流经一系列 <code>ReadProcessor</code> (读处理器)。</li>
                    <li><strong>出站 (Write):</strong> 发送到网络的数据会流经一系列 <code>WriteProcessor</code> (写处理器)。</li>
                </ul>
            </li>
            <li><strong>关键方法:</strong>
                <ul>
                    <li><code>fireWrite(Object data)</code>: 通过写处理器链启动出站数据流。</li>
                    <li><code>addReadProcessor(ReadProcessor)</code> / <code>addWriteProcessor(WriteProcessor)</code>: 将一个处理单元添加到相应的处理器链中。</li>
                    <li><code>setReadListener(ReadListener)</code> / <code>setWriteListener(WriteListener)</code>: 为最终的读/写事件（例如，数据成功读取或写入，错误）设置回调。</li>
                </ul>
            </li>
        </ul>

        <h3>ReadProcessor & WriteProcessor (读/写处理器)</h3>
        <p>这些是 <code>Pipeline</code> 内部数据处理的构建块。</p>
        <ul>
            <li><strong>ReadProcessor&lt;T&gt; (读处理器):</strong>
                <ul>
                    <li>处理类型为 <code>T</code> 的入站数据。</li>
                    <li>关键方法: <code>read(T data, ReadProcessorNode next)</code>。它接收数据和对链中下一个处理器的引用 (<code>next</code>)。为了继续流程，它必须调用 <code>next.fireRead(processedData)</code>。</li>
                    <li>也可以通过 <code>readFailed(Throwable, ReadProcessorNode)</code> 方法处理读取失败。</li>
                </ul>
            </li>
            <li><strong>WriteProcessor&lt;T&gt; (写处理器):</strong>
                <ul>
                    <li>处理类型为 <code>T</code> 的出站数据。</li>
                    <li>关键方法: <code>write(T data, WriteProcessorNode next)</code>。它接收数据和对下一个处理器的引用。为了继续，它会调用 <code>next.fireWrite(processedData)</code>。</li>
                    <li>可以通过 <code>writeFailed(WriteProcessorNode, Throwable)</code> 方法处理写入失败。</li>
                </ul>
            </li>
        </ul>

        <h3>ChannelConfig (通道配置)</h3>
        <p>在创建服务器或客户端时使用的配置对象。它保存网络通道的设置，例如 IP、端口、缓冲区大小以及要使用的 <code>AsynchronousChannelGroup</code> (线程池)。</p>
    </section>

    <section>
        <h2>使用示例</h2>

        <h3>1. 创建一个简单的 Echo 服务器</h3>
        <p>此服务器接收数据并将其回显给客户端。</p>
        <pre><code>// 1. 配置服务器
ChannelConfig config = new ChannelConfig();
config.setPort(8080); // 监听 8080 端口

// 2. 定义如何为每个新连接设置 Pipeline
PipelineInitializer initializer = pipeline -> {
    // 添加一个 ReadProcessor 来回显数据
    pipeline.addReadProcessor(new ReadProcessor&lt;Object&gt;() {
        @Override
        public void read(Object data, ReadProcessorNode next) {
            System.out.println("服务器收到: " + data);
            // 将数据回写给客户端
            pipeline.fireWrite(data);
            // 继续读取循环
            next.fireRead(data);
        }
    });
};

// 3. 创建并启动服务器
AioServer server = AioServer.newAioServer(config, initializer);
server.start();

System.out.println("Echo 服务器已在端口 8080 启动");
// server.shutdown(); // 稍后停止服务器</code></pre>

        <h3>2. 创建一个简单的 TCP 客户端</h3>
        <p>此客户端连接到 Echo 服务器并发送一条消息。</p>
        <pre><code>// 1. 配置客户端
ChannelConfig config = new ChannelConfig();
config.setIp("127.0.0.1"); // 连接到本地
config.setPort(8080);       // 连接到 8080 端口

// 2. 定义客户端连接的 Pipeline
PipelineInitializer initializer = pipeline -> {
    // 添加一个 ReadProcessor 来处理回显的数据
    pipeline.addReadProcessor(new ReadProcessor&lt;Object&gt;() {
        @Override
        public void read(Object data, ReadProcessorNode next) {
            System.out.println("客户端收到回显: " + data);
            next.fireRead(data);
        }
    });
};

// 3. 创建客户端通道
ClientChannel client = ClientChannel.newClient(config, initializer);

// 4. 连接到服务器
if (client.connect()) {
    System.out.println("已连接到服务器");
    // 5. 发送数据
    client.pipeline().fireWrite("你好，Echo 服务器!");
} else {
    System.err.println("连接失败: " + client.getConnectionException());
}</code></pre>

        <h3>3. 使用处理器构建协议</h3>
        <p>基于行的协议示例，其中消息以换行符分隔。</p>
        <pre><code>// 假设有一个假想的 LineDecoder ReadProcessor，它能根据 
 将字节缓冲区分割成字符串
// 和一个 LineEncoder WriteProcessor，它为传出的字符串添加 
。

PipelineInitializer initializer = pipeline -> {
    // 入站: 解码字节 -> 行 -> 处理业务逻辑
    pipeline.addReadProcessor(new LineDecoder()); // 将 ByteBuf 转换为 String
    pipeline.addReadProcessor(new ReadProcessor&lt;String&gt;() {
        @Override
        public void read(String line, ReadProcessorNode next) {
            System.out.println("收到行: " + line);
            if ("QUIT".equals(line)) {
                pipeline.shutdownInput(); // 干净地关闭连接
            } else {
                // 带前缀回显
                pipeline.fireWrite("回显: " + line);
            }
            next.fireRead(line);
        }
    });

    // 出站: 添加 
 -> 编码为字节
    pipeline.addWriteProcessor(new LineEncoder()); // 添加 
 并将 String 转换为 ByteBuf
    // (一个假想的 BytesEncoder 可能会在框架内部被自动添加)
};</code></pre>

        <h3>4. 使用 ReverseApp (反向代理应用)</h3>
        <p>JNet 包含一个现成的反向代理应用 <code>ReverseApp</code>。它不是一个需要编程实例化的类，而是通过其 <code>main</code> 方法直接启动的独立应用程序。其核心功能和路由规则完全由一个名为 <code>reverse.config</code> 的 YAML 配置文件驱动。</p>
        <p><strong>启动方式:</strong></p>
        <ol>
            <li>确保项目已构建完成，生成了包含所有依赖的 <code>ReverseApp.jar</code> 文件（通常在 <code>target</code> 目录下，由 <code>pom.xml</code> 中的 <code>maven-assembly-plugin</code> 配置生成）。</li>
            <li>将 <code>reverse.config</code> 配置文件放置在与 <code>ReverseApp.jar</code> 相同的目录下。</li>
            <li>通过命令行执行: <code>java -jar ReverseApp.jar</code>。</li>
        </ol>
        <p><strong>配置文件 (<code>reverse.config</code>) 说明:</strong></p>
        <p>该文件定义了监听的端口以及该端口下的路由规则。</p>
        <pre><code># reverse.config

# 监听的端口号
10180:
  # 可选的 SSL/TLS 配置
  ssl:
    enable:  false           # 是否启用 SSL
    cert:  keystore.jks      # JKS 密钥库文件路径
    password:  123456        # 密钥库密码

  # 路由规则，按顺序匹配
  # 路径: /js/* 的请求会被代理到 http://127.0.0.1:10081/js/
  /js/*:
    type:  proxy             # 类型: proxy (代理)
    path:  http://127.0.0.1:10081/js/

  # 精确匹配路径: /api/drg/cloud
  /api/drg/cloud:
    type:  proxy
    path:  http://127.0.0.1:10081
    order: 1                 # 匹配顺序，数字越小优先级越高

  # 路径前缀匹配: /api/* 的请求会被代理到 http://127.0.0.1:10086/
  /api/*:
    type:  proxy
    path:  http://127.0.0.1:10086/
    order: 2

  # 默认匹配 (根路径 /): 提供静态资源
  /:
    type:  resource          # 类型: resource (资源)
    path:  file:dist         # 本地文件系统路径 (dist 目录)
    order: 4</code></pre>
        <p>在上面的示例中，<code>ReverseApp</code> 启动后会监听 <code>10180</code> 端口。当有请求到来时：</p>
        <ul>
            <li>如果 URL 以 <code>/js/</code> 开头，则将请求转发到 <code>http://127.0.0.1:10081/js/</code>。</li>
            <li>如果 URL 是精确的 <code>/api/drg/cloud</code>，则转发到 <code>http://127.0.0.1:10081</code>。</li>
            <li>如果 URL 以 <code>/api/</code> 开头（但不是上面的精确匹配），则转发到 <code>http://127.0.0.1:10086/</code>。</li>
            <li>如果以上规则都不匹配（例如请求根路径 <code>/</code> 或 <code>/some-other-path</code>），则会尝试从本地 <code>dist</code> 目录提供静态文件资源。</li>
        </ul>
    </section>

    <section>
        <h2>关键设计原则</h2>
        <ul>
            <li><strong>异步与非阻塞:</strong> 基于 Java AIO 构建，操作不会阻塞线程，允许高并发。</li>
            <li><strong>管道架构:</strong> 通过处理器链，数据处理是模块化且可组合的。</li>
            <li><strong>显式流程控制:</strong> 处理器显式地调用链中的下一步，从而对数据流和错误处理提供精细控制。</li>
            <li><strong>资源管理:</strong> 生命周期方法 (<code>start</code>, <code>shutdown</code>) 有助于管理服务器和连接资源。</li>
        </ul>
    </section>

</body>
</html>